package proxy;


import java.lang.reflect.Method;

public class BarProxy<T> implements java.lang.reflect.InvocationHandler {
    
	Class<T> clazz = null;
	
	private BarProxy(Class<T> clazz){
		this.clazz = clazz;
	}
	
	@SuppressWarnings("unchecked")
	public static<T> T newInstance() {
	     return (T)java.lang.reflect.Proxy.newProxyInstance(
	    		 BarProxy.class.getClassLoader(),
	    		 new Class[]{Bar.class},
	             new BarProxy(Bar.class));
	}
	
    public Object invoke(Object proxy, Method m, Object[] args) throws Throwable {     
        Object result = null;
        try {
        	callMethod(this.clazz, m, args);
        } catch (Exception e) {
            e.printStackTrace();
        } 
        return result;
   }
  
   @SuppressWarnings("unchecked")
   public Object callMethod(Class clazz, Method m, Object[] args){
	  Object result = null;
	  try{ 
	     Class clazzz = Class.forName(clazz.getName()+"Impl");
   	     Object obj = clazzz.getConstructor().newInstance();
   	     result = m.invoke(obj, args);
   	     return result;
	  }catch(Exception e){
		  e.printStackTrace();
	  }
	  return null;
   }
	
   public static void main(String[] args) {
	   Bar bar = BarProxy.newInstance();
       bar.hello("proxy pattern");
       bar.goodbye("proxy pattern");
   }
}
